package com.douqu.game.main.msg;

import com.bean.core.util.Utils;
import com.douqu.game.core.config.AssetConfig;
import com.douqu.game.core.config.StableDataConfig;
import com.douqu.game.core.config.card.CardConfig;
import com.douqu.game.core.config.common.GoodsData;
import com.douqu.game.core.config.drop.DropGroupConfig;
import com.douqu.game.core.config.goods.PropConfig;
import com.douqu.game.core.config.map.CityConfig;
import com.douqu.game.core.config.map.CityDropConfig;
import com.douqu.game.core.config.map.WorldMapTaskBoxConfig;
import com.douqu.game.core.config.map.WorldMapTaskGroupConfig;
import com.douqu.game.core.controller.PlayerController;
import com.douqu.game.core.e.E_ActionPlayerType;
import com.douqu.game.core.e.E_CityInOutType;
import com.douqu.game.core.e.E_StableDataType;
import com.douqu.game.core.entity.battle.BattleTemp;
import com.douqu.game.core.entity.battle.SpriteTemp;
import com.douqu.game.core.entity.common.TwoTuple;
import com.douqu.game.core.entity.db.CardDB;
import com.douqu.game.core.entity.ext.BagInfo;
import com.douqu.game.core.entity.ext.SettingInfo;
import com.douqu.game.core.entity.ext.data.challenge.HegemonyScoreChangeBean;
import com.douqu.game.core.entity.ext.data.challenge.WorldMapKillData;
import com.douqu.game.core.entity.ext.data.challenge.WorldMapTaskData;
import com.douqu.game.core.entity.world.WorldRankBean;
import com.douqu.game.core.entity.world.map.*;
import com.douqu.game.core.factory.*;
import com.douqu.game.core.protobuf.SGCommonProto;
import com.douqu.game.core.protobuf.SGMainProto;
import com.douqu.game.core.protobuf.SGMapProto;
import com.douqu.game.core.util.CoreUtils;
import com.douqu.game.core.util.LogUtils;
import com.douqu.game.core.util.SendUtils;
import com.douqu.game.main.GameServer;
import com.douqu.game.main.server.ServerManager;
import com.douqu.game.main.server.WorldManager;
import com.douqu.game.main.server.entity.RankPlayerDetail;
import com.douqu.game.main.server.entity.ServerInfoBattle;
import com.douqu.game.main.util.WorldMapUtils;
import com.google.protobuf.InvalidProtocolBufferException;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Author: Bean
 * @Description:
 * @Date: 2018-04-17 16:34
 */
@Component
public class MapMsgChannel implements AMsgChannel {
    @Override
    public void messageChannel(int code, PlayerController playerController, byte[] data) throws Exception {
        if (playerController == null)
            throw new Exception("playerController is null");

        int beforeMilitaryExploit = playerController.getPlayer().getWorldMapTaskData().getMilitaryExploitValue();

        WorldMapData worldMapData = WorldInfoFactory.getInstance().getWorldMapData(playerController);
        if(worldMapData == null && code != SGMainProto.E_MSG_ID.MsgID_WorldMap_ArmyDetail_VALUE)//在主城也可查看军团信息
        {
            LogUtils.warn("功能没开放，禁止进入大地图 -> " + playerController.getName() + " code -> " + code);
            playerController.sendWarn(WordFactory.ILLEGAL_ERROR);
            return;
        }

//        worldMapData.removeLookCity(playerController.getObjectIndex());
        if (code == SGMainProto.E_MSG_ID.MsgID_WorldMap_Enter_VALUE) {
            enterWorldMap(playerController, data, code);
        } else if (code == SGMainProto.E_MSG_ID.MsgID_WorldMap_ArmyDetail_VALUE) {
            armyDetail(playerController, code, worldMapData);
        } else if (code == SGMainProto.E_MSG_ID.MsgID_WorldMap_UseProp_VALUE) {
            useItem(playerController, data, worldMapData);
        } else {
            SpritePlayerBean spritePlayerBean = worldMapData.getPlayerActionBean(playerController.getObjectIndex());
            if (spritePlayerBean == null)
            {
                LogUtils.error("还没进入大地图 -> " + playerController.getName() + " " + playerController.getObjectIndex() + " isSingle -> " + worldMapData.isSingle());
                playerController.sendWarn(WordFactory.ILLEGAL_ERROR);
                return;
            }

            switch (code) {
                case SGMainProto.E_MSG_ID.MsgID_WorldMap_UpdateRoute_VALUE:
                    updateRoute(playerController, data, code, spritePlayerBean);
                    break;

                case SGMainProto.E_MSG_ID.MsgID_WorldMap_ArriveCity_VALUE:
                    arriveCity(playerController, data, code, spritePlayerBean);
                    break;

                case SGMainProto.E_MSG_ID.MsgID_WorldMap_CityBaseInfo_VALUE:
                    cityBaseInfo(playerController, data, code, spritePlayerBean);
                    break;

                case SGMainProto.E_MSG_ID.MsgID_WorldMap_JoinCityQueue_VALUE:
                    inCity(playerController, code, spritePlayerBean);
                    break;

                case SGMainProto.E_MSG_ID.MsgID_WorldMap_CityDetailInfo_VALUE:
                    cityDetailInfo(playerController, data, spritePlayerBean);
                    break;

                case SGMainProto.E_MSG_ID.MsgID_WorldMap_OutCity_VALUE:
                    outCity(playerController, data, code, spritePlayerBean);
                    break;

                case SGMainProto.E_MSG_ID.MsgID_WorldMap_Challenge_VALUE:
                    challenge(playerController, data, spritePlayerBean);
                    break;

                case SGMainProto.E_MSG_ID.MsgID_WorldMap_Convene_VALUE:
                    break;

                case SGMainProto.E_MSG_ID.MsgID_WorldMap_ArmyOrder_VALUE:
                    break;

                case SGMainProto.E_MSG_ID.MsgID_WorldMap_OperAroundCity_VALUE:
                    armyBreak(playerController, data, code, spritePlayerBean);
                    break;

                case SGMainProto.E_MSG_ID.MsgID_WorldMap_TaskInfo_VALUE:
                    mapTaskInfo(playerController, code);
                    break;

                case SGMainProto.E_MSG_ID.MsgID_WorldMap_TaskReceiveBox_VALUE:
                    receiveBox(playerController, data, code);
                    break;
                /** 争霸赛积分排行 */
                case SGMainProto.E_MSG_ID.MsgID_WorldMap_HegemonyRank_VALUE:
                    integralRank(playerController, data, code);
                    break;
                case SGMainProto.E_MSG_ID.MsgID_WorldMap_Recover_VALUE:
                    recover(playerController, spritePlayerBean);
                    break;
                /** 获得城市掉落 */

                case SGMainProto.E_MSG_ID.MsgID_WorldMap_HegemonyGetCityDrop_VALUE:
                    getCityDrop(playerController, data, code, spritePlayerBean);
                    break;
                /** 膜拜 */
                case SGMainProto.E_MSG_ID.MsgID_WorldMap_Worship_VALUE:
                    worship(playerController, data, code);
                    break;

                case SGMainProto.E_MSG_ID.MsgID_WorldMap_Revive_VALUE:
                    chooseRevive(playerController, data, code, spritePlayerBean);
                    break;
            }
        }

        int afterMilitaryExploit = playerController.getPlayer().getWorldMapTaskData().getMilitaryExploitValue();
        if (beforeMilitaryExploit != afterMilitaryExploit) {
            GameServer.getInstance().getWorldManager().updateRankInfo(SGCommonProto.E_RANK_TYPE.RANK_TYPE_WORLDMAP,
                    playerController.getPlayer(), afterMilitaryExploit);
        }
    }

    private void recover(PlayerController playerController, SpritePlayerBean spritePlayerBean)
    {
        if (!spritePlayerBean.isFree() && !spritePlayerBean.isMove()) {
            LogUtils.error("只有空闲和行动状态允许进城恢复 -> " + spritePlayerBean.getStatus());
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        CityBean cityBean = WorldInfoFactory.getInstance().getWorldMapData(spritePlayerBean.getMasterPlayerIndex()).getCurCity(spritePlayerBean);
        if (cityBean == null) {
            LogUtils.error("没有在任何一个城 -> " + playerController.getName());
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }
        if(cityBean.camp != spritePlayerBean.getCamp())
        {
            LogUtils.error("不是自己的城，不能回血");
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }
        if (!cityBean.getConfig().canConscript) {
            LogUtils.error("此城没有回血功能 -> " + cityBean.getConfig().getName());
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        if (spritePlayerBean.getBattleTemp().isFull()) {
            LogUtils.error("满血状态不需要恢复 -> " + playerController.getName());
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        // 次数重置
        //playerController.getPlayer().getExtInfo(SettingInfo.class).getAutoRecover().clearItemTimes();

        WorldMapUtils.initRecover(spritePlayerBean, true);
    }

    private void armyDetail(PlayerController playerController, int code, WorldMapData worldMapData)
    {
        playerController.getPlayer().updateFC();
        SGMapProto.S2C_MapArmyDetail.Builder response = SGMapProto.S2C_MapArmyDetail.newBuilder();

        SpritePlayerBean spritePlayerBean = worldMapData != null ? worldMapData.getPlayerActionBean(playerController.getObjectIndex()) : null;

        BattleTemp battleTemp = spritePlayerBean != null ? spritePlayerBean.getBattleTemp() : null;
        if (battleTemp != null) {
            for (SpriteTemp spriteTemp : battleTemp.getSoldierList()) {
                response.addSoldier(SGCommonProto.CommonObject.newBuilder().setId(spriteTemp.getId()).setValue(spriteTemp.getHPRate()));
            }
        } else {
            for (CardDB cardDB : playerController.getPlayer().getWorldMapCardList()) {
                response.addSoldier(SGCommonProto.CommonObject.newBuilder().setId(cardDB.id).setValue(100));
            }
        }
        SettingInfo settingInfo = playerController.getPlayer().getExtInfo(SettingInfo.class);
        for(Map.Entry<Integer,Integer> e : settingInfo.getAutoRecover().getUseTimes().entrySet()){
            SGCommonProto.KeyListObject.Builder itemUseTimes = SGCommonProto.KeyListObject.newBuilder();
            itemUseTimes.setKey(e.getKey());
            itemUseTimes.setValue(e.getValue());
            response.addPropUseObjects(itemUseTimes);
        }
        playerController.sendMsg(code, response.build().toByteArray());
    }

    private void sendFailBreak(PlayerController playerController, SGMapProto.C2S_OperAroundCity request) {
        SGMapProto.S2C_OperAroundCity.Builder response = SGMapProto.S2C_OperAroundCity.newBuilder();
        response.setResult(SGCommonProto.E_UNIVERSAL_RESULT.UNIVERSAL_RESULT_FAIL);
        response.setType(request.getType());
        response.setFromCity(request.getFromCity());
        response.setToCity(request.getToCity());
        playerController.sendMsg(SGMainProto.E_MSG_ID.MsgID_WorldMap_OperAroundCity_VALUE,
                response.build().toByteArray());
    }

    private void armyBreak(PlayerController playerController, byte[] data, int code,
                           SpritePlayerBean spritePlayerBean) {
        SGMapProto.C2S_OperAroundCity request = null;
        try {
            request = SGMapProto.C2S_OperAroundCity.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            sendFailBreak(playerController, request);
            return;
        }

        if (request.getType() == SGCommonProto.E_AROUNDCITY_OPERTYPE.AROUNDCITY_OPERTYPE_UNKNOWN) {
            LogUtils.error("类型参数错误 -> " + request.getType());
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            sendFailBreak(playerController, request);
            return;
        }
        LogUtils.debug("收到突进或者撤退 -> " + request);

        WorldMapData worldMapData = WorldInfoFactory.getInstance().getWorldMapData(spritePlayerBean.getMasterPlayerIndex());

        if (!spritePlayerBean.isCanBreak()) {
            LogUtils.error("突进状态非法 -> " + spritePlayerBean.getStatus());
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            sendFailBreak(playerController, request);
            return;
        }

        CityBean fromCity = worldMapData.getCity(request.getFromCity());
        if (fromCity == null) {
            LogUtils.error("突进的起始城不存在 -> " + playerController.getName() + " city:" + request.getFromCity());
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            sendFailBreak(playerController, request);
            return;
        }

        if (spritePlayerBean.getCurCity() != fromCity.id) {
            LogUtils.error("起始城不是自己当前的城");
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            sendFailBreak(playerController, request);
            return;
        }

        CityBean toCity = worldMapData.getCity(request.getToCity());
        if (toCity == null) {
            LogUtils.error("突进的到达城不存在 -> " + playerController.getName() + " city:" + request.getToCity());
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            sendFailBreak(playerController, request);
            return;
        }

        CityConfig cityConfig = toCity.getConfig();
        if (cityConfig.type == SGCommonProto.E_CITY_TYPE.CITY_TYPE_CAPITAL_VALUE
                && cityConfig.camp != spritePlayerBean.getCamp()) {
            LogUtils.error("不能突进到别人的主城 -> " + cityConfig.getName());
            playerController.sendWarn(WordFactory.ILLEGAL_ERROR);
            sendFailBreak(playerController, request);
            return;
        }

        if (!fromCity.getConfig().isGo(request.getToCity())) {
            LogUtils.error("两个城之间没有路 -> from:" + request.getFromCity() + " to:" + request.getToCity());
            playerController.sendWarn(WordFactory.MAP_ROUTE_ERROR);
            sendFailBreak(playerController, request);
            return;
        }

        // 被围攻时不能突进或撤退,只要目标城不是自己阵营或者联盟阵营的和平城，都叫突进，否则叫撤退
        CityBean cityBean = null;
        boolean isAllBattle = true;
        for (int cityId : fromCity.getConfig().connCityIds) {
            cityBean = worldMapData.getCity(cityId);
            if (cityBean.getStatus() == SGCommonProto.E_CITY_STATUS.CITY_STATUS_PEACE
                    && cityBean.camp == spritePlayerBean.getCamp()) {
                isAllBattle = false;
                break;
            }
        }
        if (isAllBattle) {
            // 周围全是交战城,不能突进或者撤退
            LogUtils.error("周围全是交战城,不能突进或者撤退");
            playerController.sendWarn(WordFactory.MAP_BREAK_BESET);
            sendFailBreak(playerController, request);
            return;
        }

        if (request.getType() == SGCommonProto.E_AROUNDCITY_OPERTYPE.AROUNDCITY_OPERTYPE_BREAK) {
            // 突进
            SGCommonProto.E_ARMY_TEAM team = worldMapData.isAlly(spritePlayerBean.getCamp(), fromCity.camp)
                    ? SGCommonProto.E_ARMY_TEAM.ARMY_TEAM_DEF
                    : SGCommonProto.E_ARMY_TEAM.ARMY_TEAM_ATK;
            int selfCount = fromCity.getTotalArmyCount(team);
            int targetCount = toCity.getTotalArmyCount(
                    team == SGCommonProto.E_ARMY_TEAM.ARMY_TEAM_ATK ? SGCommonProto.E_ARMY_TEAM.ARMY_TEAM_DEF
                            : SGCommonProto.E_ARMY_TEAM.ARMY_TEAM_ATK);
            if (selfCount < targetCount * ConfigFactory.WORLD_MAP_BREAK_PERSON_MULT) {
                LogUtils.error("部队数不足3倍，无法突进 -> selfCount:" + selfCount + "  targetCount:" + targetCount);
                playerController.sendWarn(WordFactory.MAP_BREAK_ARMY_COUNT_ERROR);
                sendFailBreak(playerController, request);
                return;
            }
        } else if (request.getType() == SGCommonProto.E_AROUNDCITY_OPERTYPE.AROUNDCITY_OPERTYPE_RETREAT) {
            // 撤退
            if (toCity.getStatus() != SGCommonProto.E_CITY_STATUS.CITY_STATUS_PEACE) {
                LogUtils.error("撤退的城不是和平城 ->" + toCity.getStatus() + " id:" + toCity.id);
                playerController.sendWarn(WordFactory.MAP_RETREAT_CITY_NOT_PEACE);
                sendFailBreak(playerController, request);
                return;
            }

            if (!worldMapData.isAlly(spritePlayerBean.getCamp(), toCity.camp)) {
                LogUtils.error("撤退的城是敌方阵营的 ->" + toCity.getStatus() + " id:" + toCity.id);
                playerController.sendWarn(WordFactory.MAP_RETREAT_CITY_NOT_MYSELF);
                sendFailBreak(playerController, request);
                return;
            }


            BattleTemp battleTemp = spritePlayerBean.getBattleTemp();
//			if (battleTemp == null) {
//				spritePlayerBean.updateBattleTemp(battleTemp = WorldMapUtils.createBattleTemp(playerController.getPlayer(), 1, 1));
//			}

            // 生命小于指定比例的时候不允许撤退
            int beforeMasterHPRate = battleTemp.getMasterHPRate();
            int beforeArmyHPRate = battleTemp.getArmyHPRate();

            int hpRate = ConfigFactory.WORLD_MAP_BREAK_HP_RATE;
            if (beforeMasterHPRate <= hpRate || beforeArmyHPRate <= hpRate) {
                LogUtils.error("生命值太少，不能撤退");
                playerController.sendWarn(WordFactory.MAP_BREAK_HP_ERROR);
                sendFailBreak(playerController, request);
                return;
            }

//			if (spritePlayerBean.getCamp() == toCity.camp && toCity.isPeace()
//					&& toCity.getConfig().type == SGCommonProto.E_CITY_TYPE.CITY_TYPE_CAPITAL_VALUE
//					&& battleTemp != null && !battleTemp.isFull()) {
//				WorldMapUtils.initRecover(playerController.getPlayer(), spritePlayerBean, battleTemp);
//			} else {
            // 减少生命值
            double rate = hpRate * 0.01;
            battleTemp.getMaster().addHPByRate(-rate);
            for (SpriteTemp spriteTemp : battleTemp.getSoldierList()) {
                spriteTemp.addHPByRate(-rate);
            }

            WorldMapUtils.checkAutoRecover(playerController.getPlayer(), battleTemp, playerController);

            SendUtils.sendWorldMapHPUpdate(playerController);
//				playerController.getPlayer().addChangeGoods(SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_OTHER,
//						SGCommonProto.E_GOODS_OTHER_ID.GOODS_OTHER_ID_MASTER_HP_VALUE, -hpRate,
//						beforeMasterHPRate - hpRate, true);
//				playerController.getPlayer().addChangeGoods(SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_OTHER,
//						SGCommonProto.E_GOODS_OTHER_ID.GOODS_OTHER_ID_ARMY_HP_VALUE, -hpRate, beforeArmyHPRate - hpRate,
//						true);
//			}
        }

        SGMapProto.S2C_OperAroundCity.Builder response = SGMapProto.S2C_OperAroundCity.newBuilder();
        response.setResult(SGCommonProto.E_UNIVERSAL_RESULT.UNIVERSAL_RESULT_SUCCESS);
        response.setType(request.getType());
        response.setFromCity(request.getFromCity());
        response.setToCity(request.getToCity());
        playerController.sendMsg(code, response.build().toByteArray());

        LogUtils.debug("突进返回 -> " + response);

        fromCity.leave(spritePlayerBean, null, E_CityInOutType.OUT_BREAK);
        toCity.arrive(spritePlayerBean, true, E_CityInOutType.IN_BREAK);

        spritePlayerBean.clearRoute();
    }

    private void inCity(PlayerController playerController, int code, SpritePlayerBean spritePlayerBean) {
        WorldMapData worldMapData = WorldInfoFactory.getInstance().getWorldMapData(spritePlayerBean.getMasterPlayerIndex());

        CityBean cityBean = worldMapData.getCurCity(spritePlayerBean);
        if (cityBean == null) {
            LogUtils.error("城ID错误 -> " + playerController.getName() + " -> " + playerController.getObjectIndex()
                    + " city -> " + spritePlayerBean.getCurCity());
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        if (cityBean.getConfig().type == SGCommonProto.E_CITY_TYPE.CITY_TYPE_CAPITAL_VALUE) {
            LogUtils.error("这是主城，不允许进城 -> " + cityBean.id);
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }


        if (!spritePlayerBean.isFree() && !spritePlayerBean.isWait()) {
            LogUtils.error("状态错误，此时不允许进城 -> " + spritePlayerBean.getStatus());
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        // 进城,进队列
        SGCommonProto.E_CITY_STATUS beforeStatus = cityBean.getStatus();

        cityBean.in(spritePlayerBean, true, true);

        if (beforeStatus == cityBean.getStatus())
            SendUtils.sendCityDetailInfo(SGCommonProto.E_ARMY_STATUS.ARMY_STATUS_MATCH, SGCommonProto.E_ARMY_TEAM.AMRY_TEAM_ALL, cityBean, true,
                    spritePlayerBean.isAttacker(), cityBean.getStatus() == SGCommonProto.E_CITY_STATUS.CITY_STATUS_BATTLE,
                    false, playerController);

        playerController.sendMsg(code);
    }

    private void outCity(PlayerController playerController, byte[] data, int code, SpritePlayerBean spritePlayerBean) {
        SGMapProto.C2S_OutCity request = null;
        try {
            request = SGMapProto.C2S_OutCity.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        outCity(spritePlayerBean, request.getCity());

        playerController.sendMsg(code);
    }
    private void outCity(SpritePlayerBean spritePlayerBean, int cityId)
    {
        if (cityId == spritePlayerBean.getCurCity()) {
            // 当前自己在的城出城
            spritePlayerBean.setInCity(false);
        }

        // 查看的其它城出城
        WorldInfoFactory.getInstance().getWorldMapData(spritePlayerBean.getMasterPlayerIndex()).removeLookCity(spritePlayerBean.getObjectIndex());
    }

    private void cityDetailInfo(PlayerController playerController, byte[] data, SpritePlayerBean spritePlayerBean) {
        SGMapProto.C2S_CityDetailInfo request = null;
        try {
            request = SGMapProto.C2S_CityDetailInfo.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        LogUtils.debug("查看城详情 -> " + request);

        SGCommonProto.E_ARMY_STATUS reqType = request.getReqType();
        SGCommonProto.E_ARMY_TEAM team = request.getTeam();
        if (reqType == null || reqType == SGCommonProto.E_ARMY_STATUS.ARMY_STATUS_UNKNOWN || team == null
                || team == SGCommonProto.E_ARMY_TEAM.ARMY_TEAM_UNKNOWN) {
            LogUtils.error("参数错误 -> status:" + reqType + " team:" + team);
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        //准备战斗等于战斗中
        if (reqType == SGCommonProto.E_ARMY_STATUS.ARMY_STATUS_PREPARE)
            reqType = SGCommonProto.E_ARMY_STATUS.ARMY_STATUS_BATTLE;

        if (reqType != SGCommonProto.E_ARMY_STATUS.ARMY_STATUS_MATCH && reqType != SGCommonProto.E_ARMY_STATUS.ARMY_STATUS_BATTLE) {
            LogUtils.error("参数错误 -> status:" + reqType + " team:" + team);
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        WorldMapData worldMapData = WorldInfoFactory.getInstance().getWorldMapData(spritePlayerBean.getMasterPlayerIndex());

        CityBean cityBean = worldMapData.getCity(request.getCity());
        if (cityBean == null) {
            LogUtils.error("城ID错误 -> " + playerController.getName() + " -> " + playerController.getObjectIndex()
                    + " city -> " + request.getCity());
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        boolean isAttacker = false, showQueue = true;
        if (request.getCity() == spritePlayerBean.getCurCity()) {
            isAttacker = spritePlayerBean.isAttacker();
            LogUtils.debug("");
            if (spritePlayerBean.isMatch() || spritePlayerBean.isBattleOrPrepare())
                spritePlayerBean.setInCity(true);
        } else {
            showQueue = cityBean.getStatus() == SGCommonProto.E_CITY_STATUS.CITY_STATUS_BATTLE;
        }

        LogUtils.debug("查看详情 -> 是否在城里" + spritePlayerBean.isInCity());
        if (!spritePlayerBean.isInCity()) {
            worldMapData.addLookCity(cityBean, playerController.getObjectIndex());
        }

        SendUtils.sendCityDetailInfo(reqType, team, cityBean, request.getCity() == spritePlayerBean.getCurCity(), isAttacker, showQueue, false, playerController);
    }


    private void cityBaseInfo(PlayerController playerController, byte[] data, int code, SpritePlayerBean spritePlayerBean) {
        SGMapProto.C2S_CityBaseInfo request = null;
        try {
            request = SGMapProto.C2S_CityBaseInfo.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        WorldMapData worldMapData = WorldInfoFactory.getInstance().getWorldMapData(spritePlayerBean.getMasterPlayerIndex());
        CityBean cityBean = worldMapData.getCity(request.getCity());
        if (cityBean == null) {
            LogUtils.error("查看的城不存在 -> " + request.getCity());
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        SGMapProto.S2C_CityBaseInfo.Builder response = SGMapProto.S2C_CityBaseInfo.newBuilder();
        response.setCity(request.getCity());
        response.addAllAttacker(cityBean.parseArmyBaseList(SGCommonProto.E_ARMY_TEAM.ARMY_TEAM_ATK));
        response.addAllDefender(cityBean.parseArmyBaseList(SGCommonProto.E_ARMY_TEAM.ARMY_TEAM_DEF));
        response.setCityStatus(cityBean.getStatus());

        playerController.sendMsg(code, response.build().toByteArray());
    }

    /**
     * 进入或者退出大地图
     *
     * @param playerController
     * @param data
     * @param code
     */
    private void enterWorldMap(PlayerController playerController, byte[] data, int code) {
        SGMapProto.C2S_EnterWorldMap request = null;
        try {
            request = SGMapProto.C2S_EnterWorldMap.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        LogUtils.debug("进大地图 -> " + request.getFlag() + "  inWorldMap -> " + playerController.isInWorldMap());

        if (!playerController.isFree()) {
            LogUtils.error("不是空闲状态 -> " + playerController.getName());
            playerController.sendWarn(WordFactory.ILLEGAL_ERROR);
            return;
        }

        WorldMapData worldMapData = WorldInfoFactory.getInstance().getWorldMapData(playerController);
        if(worldMapData == null)
        {
            LogUtils.error("功能没开放，不允许进入 -> " + playerController.getName());
            playerController.sendWarn(WordFactory.ILLEGAL_ERROR);
            return;
        }
        SpritePlayerBean removePlayerBean = null;
        if(worldMapData.isSingle())
        {
            /**
             * 1.新进大地图，等级限制在单人战场
             * 2.战斗回来进大地图，之前就已经在大地图
             * 3.出大地图，由于之前就已经在单人战场，所以这里取出的还是单人战场，要检测是否应该离开单人战场了，要加入到世界地图中
             */
            if(!request.getFlag())
            {
                //退出大地图时,检测一下是否应该切换到世界地图了
                if(!WorldInfoFactory.getInstance().isSingleWorldMapByLv(playerController.getPlayer()))
                {
                    //已经应该切换到世界地图了
                    removePlayerBean = WorldInfoFactory.getInstance().removeSingleWorldMap(playerController.getObjectIndex());
                    worldMapData = WorldInfoFactory.getInstance().getWorldMapData();
                }
            }
        }
        else
            removePlayerBean = WorldInfoFactory.getInstance().removeSingleWorldMap(playerController.getObjectIndex());

        LogUtils.debug("是否是单人战场　 -> " + worldMapData.isSingle());

        SpritePlayerBean spritePlayerBean = worldMapData.getPlayerActionBean(playerController.getObjectIndex());
        LogUtils.debug("  当前所在城" + worldMapData.getSpriteCurCity(playerController.getObjectIndex()));
        LogUtils.debug("---------------spritePlayerBean -> " + spritePlayerBean);
        if (spritePlayerBean == null) {
//            if (!request.getFlag()) {
//                LogUtils.error("还没进入你就退出? -> " + playerController.getName());
//                playerController.sendWarn(WordFactory.PARAM_ERROR);
//                return;
//            }

            spritePlayerBean = worldMapData.initActionBean(E_ActionPlayerType.ONLINE_MAP, playerController, removePlayerBean==null);
            BattleTemp battleTempCache = WorldInfoFactory.getInstance().getCacheBattleTemp(playerController.getObjectIndex());
            if(battleTempCache != null)
            {
                if(removePlayerBean != null && removePlayerBean.getStatus() == SGCommonProto.E_ARMY_STATUS.ARMY_STATUS_RECOVER)
                {
                    spritePlayerBean.setRecoverParam(removePlayerBean.getRecoverParam());
                    spritePlayerBean.setStatus(SGCommonProto.E_ARMY_STATUS.ARMY_STATUS_RECOVER);
                }

                spritePlayerBean.updateBattleTemp(battleTempCache);
                WorldInfoFactory.getInstance().removeCacheBattleTemp(playerController.getObjectIndex());
            }
        }

        spritePlayerBean.setActionPlayerType(
                request.getFlag() ? E_ActionPlayerType.ONLINE_MAP : E_ActionPlayerType.ONLINE,
                request.getFlag() ? 0 : DataFactory.currentTime);

        spritePlayerBean.setPlayerController(playerController);
        if(!worldMapData.isSingle())
        {
            playerController.setSingleWorldMap(false);
            playerController.getPlayer().getWorldMapTaskData().setSingleMapEnd(true);
        }

        if (request.getFlag()) {
            SGMapProto.S2C_EnterWorldMap.Builder response = SGMapProto.S2C_EnterWorldMap.newBuilder();
            response.setFlag(request.getFlag());
            response.setCurCity(spritePlayerBean.getCurCity());
            response.addAllCityItem(worldMapData.parseList());
            response.addAllRoute(spritePlayerBean.getRouteList());
            response.setArmyStatus(spritePlayerBean.getStatus());
            WorldMapKillData killData = playerController.getPlayer().getWorldMapTaskData().getKillData();
            response.setIsShowRank(killData.isFirstEnter());
            WorldMapKillData worldMapKillData = playerController.getPlayer().getWorldMapKillData();
            SGCommonProto.CommonObject.Builder common = SGCommonProto.CommonObject.newBuilder();
            common.setId(worldMapKillData.getSkillCount());
            common.setValue(worldMapKillData.getCurrentTotalScore());
            response.setInitHegemony(common);
            response.addAllDropInfoList(worldMapData.initMyDropCityInfo(playerController.getPlayer()));
            response.setIsHegemony(worldMapData.hegemonyIsSettle(playerController.getPlayer()));
            SettingInfo settingInfo = playerController.getPlayer().getExtInfo(SettingInfo.class);
            for(Map.Entry<Integer,Integer> e : settingInfo.getAutoRecover().getUseTimes().entrySet()){
                SGCommonProto.KeyListObject.Builder itemUseTimes = SGCommonProto.KeyListObject.newBuilder();
                itemUseTimes.setKey(e.getKey());
                itemUseTimes.setValue(e.getValue());
                response.addPropUseObjects(itemUseTimes);
            }
            playerController.sendMsg(code, response.build().toByteArray());

            SendUtils.sendMapArmyStatus(playerController, spritePlayerBean.getStatus());
//            if(spritePlayerBean.getStatus() == SGCommonProto.E_ARMY_STATUS.ARMY_STATUS_RECOVER)
//                SendUtils.sendWorldMapHPUpdate(playerController, 10);

            spritePlayerBean.setOutMapTime(0);
            playerController.setInWorldMap(true);
        } else {
            // 退出大地图
            spritePlayerBean.setOutMapTime(DataFactory.currentTime);
            playerController.setInWorldMap(false);

            outCity(spritePlayerBean, spritePlayerBean.getCurCity());
        }
    }

    /**
     * 前端发来路线
     */
    private void updateRoute(PlayerController playerController, byte[] data, int code,
                             SpritePlayerBean spritePlayerBean) {
        SGMapProto.C2S_UpdateRoute request = null;
        try {
            request = SGMapProto.C2S_UpdateRoute.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }
        if (request.getCityList() == null || request.getCityList().isEmpty()) {
            LogUtils.error("路线列表参数错误 -> " + request.getCityList());
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        List<Integer> routeList = new ArrayList<>();
        routeList.addAll(request.getCityList());
        if (routeList.size() == 1) {
            routeList.add(0, spritePlayerBean.getCurCity());
            LogUtils.debug("只有一个点，把它当前的点增加到路线里");
        }

        LogUtils.debug("收到路线 -> " + routeList);

        int size = routeList.size();
        for (int i = 0; i < size; i++) {
            if (i > 0 && routeList.get(i) == routeList.get(i - 1)) {
                LogUtils.error("列表里有重复值 -> " + routeList);
                playerController.sendWarn(WordFactory.PARAM_ERROR);
                return;
            }
        }

        if (!playerController.isFree()) {
            LogUtils.error("玩家状态不为空闲，不能行动 -> " + playerController.getStatus());
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        WorldMapData worldMapData = WorldInfoFactory.getInstance().getWorldMapData(spritePlayerBean.getMasterPlayerIndex());

        if (!spritePlayerBean.isFree() && !spritePlayerBean.isMove()) {
            LogUtils.error("玩家状态不为空闲，不能行动 -> " + spritePlayerBean.getStatus());
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        CityConfig cityConfig = null;
        DataFactory dataFactory = DataFactory.getInstance();
        for (int i = 0; i < size; i++) {
            cityConfig = dataFactory.getGameObject(DataFactory.CITY_KEY, routeList.get(i));
            if (cityConfig == null) {
                LogUtils.error("没有这个城 -> " + routeList.get(i));
                playerController.sendWarn(WordFactory.PARAM_ERROR);
                return;
            }

            if (i < size - 1) {
                if (!cityConfig.isGo(routeList.get(i + 1))) {
                    LogUtils.error("路线不通 : " + routeList.get(i) + " -> " + routeList.get(i + 1));
                    playerController.sendWarn(WordFactory.MAP_ROUTE_ERROR);
                    return;
                }
            }

            if (i == size - 1) {
                if (cityConfig.type == SGCommonProto.E_CITY_TYPE.CITY_TYPE_CAPITAL_VALUE
                        && cityConfig.camp != spritePlayerBean.getCamp()) {
                    LogUtils.error("不能到达别人的主城 -> " + routeList.get(i));
                    playerController.sendWarn(WordFactory.PARAM_ERROR);
                    return;
                }
            }
        }

        List<Integer> checkList = routeList.subList(0, size - 1);
        CityBean cityBean = null;
        for (Integer id : checkList) {
            cityBean = worldMapData.getCity(id);
            if (cityBean == null) {
                LogUtils.error("没有这个城 -> " + id);
                playerController.sendWarn(WordFactory.PARAM_ERROR);
                return;
            }

            if (!cityBean.isPeace()) {
                LogUtils.error("城的状态不是和平 -> id:" + id + " status:" + cityBean.getStatus());
                playerController.sendWarn(WordFactory.MAP_ROUTE_ERROR);
                return;
            } else {
                if (!worldMapData.isAlly(playerController.getPlayer().camp, cityBean.camp)) {
                    LogUtils.error("不是我自己阵营的城，也不是联盟阵营的城 -> id:" + id + " camp:" + cityBean.camp + " myCamp:"
                            + playerController.getPlayer().camp);
                    playerController.sendWarn(WordFactory.MAP_ROUTE_ERROR);
                    return;
                }
            }
        }

        int startCity = routeList.get(0);
        if (spritePlayerBean.getCurCity() != startCity) {
            int nextCity = spritePlayerBean.getNextCity();
            int secondCity = routeList.get(1);
            if (nextCity != startCity && secondCity != spritePlayerBean.getCurCity() && spritePlayerBean.getStartCity() != startCity) {
                LogUtils.error("路线起点不是玩家当前所在城，也不是上次的起点 -> nextCity: " + nextCity + " startCity:" + startCity
                        + " curIndex:" + spritePlayerBean.getCurRouteIndex() + " curCity:" + spritePlayerBean.getCurCity() + " secondCity:" + secondCity);
                playerController.sendWarn(WordFactory.MAP_ROUTE_ERROR);
                return;
            } else {
                LogUtils.debug("新的路线的起点是上一个城的下一点，可以通过，下面开始设置数据");
                if (DataFactory.currentTime - spritePlayerBean.getLastUpdateStatusTime() > 1000) {
                    spritePlayerBean.setLastUpdateStatusTime(DataFactory.currentTime);
                } else {
                    spritePlayerBean.setLastUpdateStatusTime(spritePlayerBean.getLastUpdateStatusTime() + 1000);
                }
            }
        }

        spritePlayerBean.initRoute(routeList);

        LogUtils.debug("路线设置成功 -> " + routeList);

        SGMapProto.S2C_UpdateRoute.Builder response = SGMapProto.S2C_UpdateRoute.newBuilder();
        response.addAllCity(request.getCityList());
        response.setCurCity(spritePlayerBean.getCurCity());
        playerController.sendMsg(code, response.build().toByteArray());

//		CityConfig mainCity = DataFactory.getInstance().getMainCityByCamp(spritePlayerBean.getCamp());
//		if (spritePlayerBean.getCurCity() == mainCity.id) {
//			WorldMapTaskData worldMapTaskData = playerController.getPlayer().getWorldMapTaskData();
//			worldMapTaskData.setBattleCardList(playerController.getPlayer().getBagInfo().getCardData().getBattleCardList());
//		}
    }

    /**
     * 到达城市
     *
     * @param playerController
     * @param data
     * @param code
     */
    private void arriveCity(PlayerController playerController, byte[] data, int code,
                            SpritePlayerBean spritePlayerBean) {
        SGMapProto.C2S_ArriveCity request = null;

        try {
            request = SGMapProto.C2S_ArriveCity.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        int targetCity = request.getCity();
        WorldMapData worldMapData = WorldInfoFactory.getInstance().getWorldMapData(spritePlayerBean.getMasterPlayerIndex());
        CityBean cityBean = worldMapData.getCity(targetCity);
        if (cityBean == null) {
            LogUtils.error("城不存在 -> " + targetCity);
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        LogUtils.debug("收到到达城 -> " + request);

        if (targetCity == spritePlayerBean.getCurCity()) {
//			LogUtils.error("到达城和当前所在城相同 -> " + playerController.getName() + " -> " + targetCity);
            SGMapProto.S2C_ArriveCity.Builder response = SGMapProto.S2C_ArriveCity.newBuilder();
            response.setCity(targetCity);
            response.setStatus(spritePlayerBean.getStatus());
            playerController.sendMsg(code, response.build().toByteArray());
            return;
        }

        CityConfig cityConfig = cityBean.getConfig();
        if (cityConfig.type == SGCommonProto.E_CITY_TYPE.CITY_TYPE_CAPITAL_VALUE
                && cityConfig.camp != spritePlayerBean.getCamp()) {
            LogUtils.error("不能到达别人的主城 -> " + cityConfig.getName());
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }


        if (DataFactory.currentTime - spritePlayerBean.getLastUpdateStatusTime() < 1000
                && spritePlayerBean.getCurRouteIndex() > 0) {
            LogUtils.error("请不要使用加速器 -> " + playerController.getName());
            playerController.sendWarn(WordFactory.ILLEGAL_ERROR);
            return;
        }

        int curCityId = spritePlayerBean.move(targetCity);
        if (curCityId == 0 || curCityId != targetCity) {
            LogUtils.error("到达城错误 -> " + playerController.getName() + " -> " + targetCity + " index:"
                    + spritePlayerBean.getCurRouteIndex() + " 路线:" + spritePlayerBean.getRouteList());
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            // playerController.sendWarn("到达城错误 -> " + targetCity);
            return;
        }

//		CityBean curCity = worldMapData.getCity(curCityId);
        LogUtils.debug("移动后现在的当前城 -> " + cityBean);
        if (!request.getIsGo() || cityBean.getStatus() != SGCommonProto.E_CITY_STATUS.CITY_STATUS_PEACE) {
            spritePlayerBean.stop();
            cityBean.arrive(spritePlayerBean, true, E_CityInOutType.IN_DEFAULT_ARRIVE);
        } else {
            cityBean.arrive(spritePlayerBean, spritePlayerBean.isFree(), E_CityInOutType.IN_DEFAULT_ARRIVE);
        }

//		BattleTemp battleTemp = GameServer.getInstance().getWorldManager().getSpriteBattleTemp(
//				SGCommonProto.E_BATTLE_TYPE.BATTLE_TYPE_WORLD_MAP_VALUE, spritePlayerBean.getObjectIndex());
//		if (spritePlayerBean.getCamp() == cityBean.camp && spritePlayerBean.isEndRoute() && cityBean.isPeace()
//				&& cityBean.getConfig().canConscript && battleTemp != null && !battleTemp.isFull()) {
//			WorldMapUtils.initRecover(playerController.getPlayer(), spritePlayerBean, battleTemp);
//		}

        LogUtils.debug("到达城  -> " + targetCity + " curIndex:" + spritePlayerBean.getCurRouteIndex() + " routeList:"
                + spritePlayerBean.getRouteList());

        SGMapProto.S2C_ArriveCity.Builder response = SGMapProto.S2C_ArriveCity.newBuilder();
        response.setCity(targetCity);
        response.setStatus(spritePlayerBean.getStatus());

        playerController.sendMsg(code, response.build().toByteArray());
    }

    /*************** 战场争锋 *********************************/

    /**
     * 初始化战场争锋
     *
     * @param playerController
     * @param code
     */
    private void mapTaskInfo(PlayerController playerController, int code) {
        SGMapProto.S2C_MapTaskInfo.Builder response = SGMapProto.S2C_MapTaskInfo.newBuilder();

        // 获取该用户的WorldMapTaskInfo
        WorldMapTaskData mapTaskInfo = playerController.getPlayer().getWorldMapTaskData();

        int myRank = 0;
        if (mapTaskInfo.getMilitaryExploitValue() > 0) {
            // 有排行 否则没有排行啊
            List<WorldRankBean> rankBeanList = GameServer.getInstance().getWorldManager()
                    .getRankList(SGCommonProto.E_RANK_TYPE.RANK_TYPE_WORLDMAP);
            WorldRankBean rankBean;
            for (int i = 0; i < rankBeanList.size(); i++) {
                rankBean = rankBeanList.get(i);
                if (rankBean.getObjectIndex().equals(playerController.getObjectIndex())) {
                    myRank = i + 1;
                    break;
                }
            }
        }
        response.setTodayKillRanks(myRank);// 0表示暂无排行
        response.addAllBoxList(mapTaskInfo.getBoxList());
        response.setTodayExp(mapTaskInfo.getTodayExp());

        playerController.sendMsg(code, response.build().toByteArray());
    }

    /**
     * 战场争锋领取宝箱
     *
     * @param playerController
     * @param data
     * @param code
     */
    private void receiveBox(PlayerController playerController, byte[] data, int code) {
        SGMapProto.C2S_MapTaskReceiveBox request = null;
        try {
            request = SGMapProto.C2S_MapTaskReceiveBox.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }

        if (request == null) {
            // 参数错误
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        int boxId = request.getBoxId();
        /**
         * 1.取到这个宝箱 如果为空则是参数错误 2.判断这个宝箱的需求的军功 看该用户是否达到 3.判断是否领取过这个宝箱了
         * 4.判断这个宝箱所在组的级别是否与该用户一致
         */
        WorldMapTaskBoxConfig boxConfig = WorldMapTaskData.getWorldMapTaskBoxConfig(boxId);
        if (boxConfig == null) {
            playerController.sendWarn(WordFactory.MAP_TASK_BOX_UN_EXIST);
            return;
        }
        WorldMapTaskData mapTaskInfo = playerController.getPlayer().getWorldMapTaskData();
        if (boxConfig.needCount > mapTaskInfo.getMilitaryExploitValue()) {
            playerController.sendWarn(WordFactory.MAP_MILITARY_EXPLOIT_NOT_ENOUGH);
            return;
        }
        WorldMapTaskGroupConfig startValueConfig = WorldMapTaskData.getWorldMapTaskValueConfig(boxConfig.group);
        if (startValueConfig == null) {
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        if (mapTaskInfo.getBoxList().contains(Integer.valueOf(boxId))) {
            playerController.sendWarn(WordFactory.MAP_TASK_BOX_ALREADY_RECEIVE);
            return;
        }

        if (startValueConfig.level > mapTaskInfo.getLastGrade()) {
            playerController.sendWarn(WordFactory.MAP_TASK_BOX_NOT_BELONG);
            return;
        }
        WorldMapTaskGroupConfig endValueConfig = WorldMapTaskData.getWorldMapTaskValueConfig(boxConfig.group + 1);
        if (endValueConfig != null && endValueConfig.level <= mapTaskInfo.getLastGrade()) {
            playerController.sendWarn(WordFactory.MAP_TASK_BOX_NOT_BELONG);
            return;
        }

        // 合适 可以领取宝箱
        BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
        bagInfo.addGoods(boxConfig.reward);
        mapTaskInfo.getBoxList().add(boxId);

        SGMapProto.S2C_MapTaskReceiveBox.Builder response = SGMapProto.S2C_MapTaskReceiveBox.newBuilder();
        response.setBoxId(boxId);
        response.addAllBoxList(mapTaskInfo.getBoxList());
        playerController.sendMsg(code, response.build().toByteArray());
    }

    public void challenge(PlayerController playerController, byte[] data, SpritePlayerBean spritePlayerBean) {
        SGMapProto.C2S_CityChallenge request = null;
        try {
            request = SGMapProto.C2S_CityChallenge.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        WorldMapData worldMapData = WorldInfoFactory.getInstance().getWorldMapData(spritePlayerBean.getMasterPlayerIndex());

        if (!spritePlayerBean.isInCity()) {
            LogUtils.error("不在城详情里面,不能挑战 -> " + playerController.getName());
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        if (!spritePlayerBean.isMatch()) {
            LogUtils.error("匹配状态错误 -> " + playerController.getName() + " " + playerController.getObjectIndex());
//            playerController.sendWarn(WordFactory.PARAM_ERROR);
            playerController.sendUnknown();
            return;
        }

        CityBean cityBean = worldMapData.getCurCity(spritePlayerBean);
        if (cityBean == null) {
            LogUtils.error("数据异常，玩家不在任何一个城 -> " + playerController.getName() + " " + playerController.getObjectIndex());
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        if (!cityBean.getConfig().canBattle) {
            LogUtils.error("这个城不允许战斗 -> " + cityBean.id);
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        if (cityBean.isGarrisonRefreshing()) {
            LogUtils.error("守卫正在初始化中，请稍候再试");
            playerController.sendWarn(WordFactory.MAP_GARRISON_BUSY);
            return;
        }

        ServerInfoBattle serverInfo = ServerManager.getInstance().getFreeBattleServer();
        if (serverInfo == null) {
            LogUtils.error("战斗服务器没有开启");
            playerController.sendWarn(WordFactory.BATTLE_SERVER_ERROR);
            return;
        }

        String targetIndex = request.getPlayerIndex();
        if(!Utils.isNull(targetIndex))
        {
            //攻击指定对象
            SpriteBean target = cityBean.getSpriteBean(targetIndex);
            if (target == null || !target.isMatch()) {
                LogUtils.error("选择的挑战对象不存在 -> " + playerController.getName() + " " + playerController.getObjectIndex() + " target:" + targetIndex);
                playerController.sendWarn(WordFactory.MAP_MATCH_NO_TARGET);
                return;
            }

            if (target != null && target.isInProtectTime()) {
                LogUtils.debug("目标还在保护期间内，请稍候再试 -> " + target);
                playerController.sendWarn(WordFactory.MAP_MATCH_NO_TARGET);
                return;
            }

            if(target.getTeam() == spritePlayerBean.getTeam())
            {
                LogUtils.error("不能攻击队友 -> " + target.getName());
                playerController.sendWarn(WordFactory.ILLEGAL_ERROR);
                return;
            }

//            MapMatchTeam mapMatchTeam = new MapMatchTeam(spritePlayerBean, target, ConfigFactory.WORLD_MAP_BATTLE_WAIT_TIME, cityBean.id, DataFactory.getInstance().getMapIdByWorldMap(cityBean.camp));
//            worldMapData.addMatchTeam(mapMatchTeam);
//
//            SendUtils.sendMapChallenge(mapMatchTeam);
//
//            SendUtils.sendChangeQueue(cityBean, mapMatchTeam);
        }
        else
        {
            //设置这个值为true,让它去匹配线程匹配,保证只在一个线程做匹配操作
//            spritePlayerBean.setManualMatch(true);
        }

        spritePlayerBean.setManualMatch(true, targetIndex);

        cityBean.setOccupyCityParam(null);
    }


    /**
     * 争霸赛积分排行
     *
     * @param playerController
     * @param data
     * @param code
     */
    private void integralRank(PlayerController playerController, byte[] data, int code) {
        SGMapProto.C2S_MapHegemonyRank request = null;
        try {
            request = SGMapProto.C2S_MapHegemonyRank.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        SGCommonProto.E_RANK_TYPE rankType = request.getType();

        if (rankType != SGCommonProto.E_RANK_TYPE.RANK_TYPE_MAPCURRWEEK
                && rankType != SGCommonProto.E_RANK_TYPE.RANK_TYPE_MAPLASTWEEK) {
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }
        int rankIndex = 0;
        WorldManager worldManager = GameServer.getInstance().getWorldManager();
        List<WorldRankBean> rankBeanList = worldManager.getRankList(rankType);

        SGMapProto.S2C_MapHegemonyRank.Builder response = SGMapProto.S2C_MapHegemonyRank.newBuilder();

        response.setRankType(rankType);

        response.setHegemonyRankType(worldManager.getRankStatus(rankType));

        RankPlayerDetail rankPlayerDetail = null;
        SGCommonProto.HegemonyRankItem.Builder rankBean = null;
        WorldMapKillData killData = playerController.getPlayer().getWorldMapKillData();
        for (WorldRankBean bean : rankBeanList) {
            rankBean = SGCommonProto.HegemonyRankItem.newBuilder();
            rankPlayerDetail = worldManager.getRankPlayer(bean.getObjectIndex());

            if (rankPlayerDetail == null) {
                LogUtils.error("玩家已被删除,请检查 -> " + bean.getObjectIndex());
            } else {
                rankBean.setIndex(++rankIndex);
                rankBean.setName(rankPlayerDetail.getName());
                rankBean.setServerName(rankPlayerDetail.getServerName());
                rankBean.setCamp(SGCommonProto.E_CAMP_TYPE.forNumber(rankPlayerDetail.getCamp()));
                rankBean.setMaxIntegral((int)bean.getValue());
                rankBean.setTotalIntegral(rankPlayerDetail.getTotalIntegral());
                rankBean.setPlayerIndex(rankPlayerDetail.getObjectIndex());
                if (rankType.equals(SGCommonProto.E_RANK_TYPE.RANK_TYPE_MAPLASTWEEK)) {
                    rankBean.setCanWorship(killData.isAlreadyWorship(bean.getObjectIndex()));
                }
                response.addAllrank(rankBean);
            }
        }

        int selfRank = worldManager.getRankByPlayer(playerController.getPlayer(), rankType);
        // 说明玩家有排行
        if (selfRank > 0) {
            for (int i = 0; i < 2; i++) {
                // 第一次循环 与 第二次循环
                if (i == 1 || (i == 0 && selfRank > 1)) {
                    // 排名比index 大一
                    WorldRankBean selfBean = worldManager.getRankByIndex(rankType, selfRank - 2 + i);
                    if (selfBean == null) {
                        continue;
                    }
                    rankPlayerDetail = worldManager.getRankPlayer(selfBean.getObjectIndex());
                    rankBean = SGCommonProto.HegemonyRankItem.newBuilder();
                    rankBean.setIndex(selfRank - 1 + i);
                    rankBean.setName(rankPlayerDetail.getName());
                    rankBean.setServerName(rankPlayerDetail.getServerName());
                    rankBean.setCamp(SGCommonProto.E_CAMP_TYPE.forNumber(rankPlayerDetail.getCamp()));
                    rankBean.setMaxIntegral((int)selfBean.getValue());
                    rankBean.setTotalIntegral(rankPlayerDetail.getTotalIntegral());
                    rankBean.setPlayerIndex(rankPlayerDetail.getObjectIndex());
                    response.addMyrank(rankBean);
                }
            }
        } else {
            //如果玩家未上榜
            rankBean = SGCommonProto.HegemonyRankItem.newBuilder();
            rankBean.setIndex(0);
            rankBean.setName(playerController.getName());
            rankBean.setServerName(WorldInfoFactory.getInstance().getName());
            rankBean.setCamp(SGCommonProto.E_CAMP_TYPE.forNumber(playerController.getPlayer().camp));
            rankBean.setMaxIntegral(0);
            rankBean.setTotalIntegral(0);
            rankBean.setPlayerIndex(playerController.getObjectIndex());
            response.addMyrank(rankBean);
        }
        response.setRewardGroupKey(WorldInfoFactory.getInstance().getWorldRankData().getRewardGroup(rankType).groupId);
        response.setEndTime(CoreUtils.getWeekEndTime());
        playerController.sendMsg(code, response.build().toByteArray());
    }

    /**
     * 复活
     *
     * @param playerController
     * @param data
     * @param code
     * @param spritePlayerBean
     */
    private void chooseRevive(PlayerController playerController, byte[] data, int code,
                              SpritePlayerBean spritePlayerBean) {
        SGMapProto.C2S_MapRevive request = null;
        try {
            request = SGMapProto.C2S_MapRevive.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        if (spritePlayerBean.getStatus() != SGCommonProto.E_ARMY_STATUS.ARMY_STATUS_DIE) {
            LogUtils.error("状态错误，不是死亡状态，不能复活 -> " + spritePlayerBean.getStatus());
            playerController.sendWarn(WordFactory.STATUS_ERROR);
            return;
        }

        StableDataConfig stableDataConfig = null;
        // 判断道具是否足够
        if (request.getReviveType() == SGCommonProto.E_REVIVE_TYPE.REVIVE_TYPE_NORMAL) {
            // 普通
            stableDataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY,
                    E_StableDataType.REVIVE_NORMAL.getCode());
        } else if (request.getReviveType() == SGCommonProto.E_REVIVE_TYPE.REVIVE_TYPE_PERFECT) {
            // 完美
            stableDataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY,
                    E_StableDataType.REVIVE_PERFECT.getCode());
        } else if (request.getReviveType() == SGCommonProto.E_REVIVE_TYPE.REVIVE_TYPE_WONDEFUL) {
            // 至尊
            stableDataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY,
                    E_StableDataType.REVIVE_WONDEFUL.getCode());
        }

        int reviveTimes = playerController.getPlayer().getExtInfo(SettingInfo.class).getAutoRecover().getUseTimes(ConstantFactory.PROP_TYPE_REVIVE);
        if (stableDataConfig != null) {
            GoodsData goodsData;
            if (reviveTimes >= stableDataConfig.goods.length) {
                goodsData = stableDataConfig.goods[stableDataConfig.goods.length - 1];
            } else {
                goodsData = stableDataConfig.goods[reviveTimes];
            }

            // 道具数量是否足够
            if (goodsData != null) {
                BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
                GoodsData[] result = bagInfo.rechargIfItemNotEnghou(goodsData);
                if (result == null) {
                    playerController.sendWarn(WordFactory.GOODS_NOT_ENOUGH, goodsData.id);
                    return;
                }
                bagInfo.subGoods(result); // 扣除道具
            }
        }

        if (request.getReviveType() == SGCommonProto.E_REVIVE_TYPE.REVIVE_TYPE_UNKNOWN) {
            // 回城
            WorldInfoFactory.getInstance().getWorldMapData(spritePlayerBean.getMasterPlayerIndex()).backMainCity(spritePlayerBean, SGCommonProto.E_ARMY_STATUS.ARMY_STATUS_RECOVER, true);
            //不复活 争霸赛连胜终结
            WorldMapUtils.initRecover(spritePlayerBean, true);
        } else if (request.getReviveType() == SGCommonProto.E_REVIVE_TYPE.REVIVE_TYPE_NORMAL) {
            spritePlayerBean.updateBattleTemp(WorldMapUtils.createBattleTemp(playerController.getPlayer(), 0.3, 0.3));
            WorldMapUtils.checkAutoRecover(playerController.getPlayer(), spritePlayerBean.getBattleTemp(), playerController);
        } else if (request.getReviveType() == SGCommonProto.E_REVIVE_TYPE.REVIVE_TYPE_PERFECT) {
            spritePlayerBean.updateBattleTemp(WorldMapUtils.createBattleTemp(playerController.getPlayer(), 1, 1));
            WorldMapUtils.checkAutoRecover(playerController.getPlayer(), spritePlayerBean.getBattleTemp(), playerController);
        } else if (request.getReviveType() == SGCommonProto.E_REVIVE_TYPE.REVIVE_TYPE_WONDEFUL) {
            // 至尊复活，暂不实现
        } else {
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }


        if (request.getReviveType() == SGCommonProto.E_REVIVE_TYPE.REVIVE_TYPE_NORMAL || request.getReviveType() == SGCommonProto.E_REVIVE_TYPE.REVIVE_TYPE_PERFECT
                || request.getReviveType() == SGCommonProto.E_REVIVE_TYPE.REVIVE_TYPE_WONDEFUL) {
            CityBean cityBean = WorldInfoFactory.getInstance().getWorldMapData(spritePlayerBean.getMasterPlayerIndex()).getCurCity(spritePlayerBean);
            cityBean.revive(spritePlayerBean);
            // 增加复活次数
            playerController.getPlayer().getExtInfo(SettingInfo.class).getAutoRecover().addUseTimes(ConstantFactory.PROP_TYPE_REVIVE);

            // 推送血量更新
            SendUtils.sendWorldMapHPUpdate(playerController);
        }

        SGMapProto.S2C_MapRevive.Builder response = SGMapProto.S2C_MapRevive.newBuilder();
        response.setReviveTimes(reviveTimes + 1);
        playerController.sendMsg(code, response.build().toByteArray());
    }

    private void useItem(PlayerController playerController, byte[] data, WorldMapData worldMapData) {
        SGMapProto.C2S_WorldMapUseProp request = null;
        try {
            request = SGMapProto.C2S_WorldMapUseProp.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        PropConfig propConfig = DataFactory.getInstance().getGameObject(DataFactory.PROP_KEY, request.getPropId());
        if (propConfig == null) {
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        SpritePlayerBean spritePlayerBean = worldMapData.getPlayerActionBean(playerController.getObjectIndex());
        if (propConfig.type == ConstantFactory.PROP_TYPE_RECOVER) {
            // 使用恢复类道具
            useRecoverItem(playerController, spritePlayerBean);
        } else if (propConfig.type == ConstantFactory.PROP_TYPE_REVIVE) {
            // 使用复活类道具
            useReviveItem(playerController, spritePlayerBean);
        } else {
            playerController.sendWarn(WordFactory.PARAM_ERROR);
        }
    }

    /**
     * 大地图手动使用回复道具
     *
     * @param playerController
     * @param spritePlayerBean
     */
    private void useRecoverItem(PlayerController playerController, SpritePlayerBean spritePlayerBean) {
        // 血量是否满
        if (spritePlayerBean == null || spritePlayerBean.getBattleTemp().isFullByLive()) {
            playerController.sendWarn(WordFactory.HP_IS_FULL);
            return;
        }

        if (!spritePlayerBean.isFree() && !spritePlayerBean.isMove() && !spritePlayerBean.isWait() && !spritePlayerBean.isMatch()) {
            LogUtils.error("只有空闲、行动、待命、匹配状态允许使用 -> " + spritePlayerBean.getStatus());
            playerController.sendWarn(WordFactory.STATUS_ERROR);
            return;
        }

        StableDataConfig stableDataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY,
                E_StableDataType.RECOVER_ITEM.getCode());
        GoodsData goodsData;
        int useHealthItemTimes = playerController.getPlayer().getExtInfo(SettingInfo.class).getAutoRecover().getUseTimes(ConstantFactory.PROP_TYPE_RECOVER);
        if (useHealthItemTimes >= stableDataConfig.goods.length) {
            goodsData = stableDataConfig.goods[stableDataConfig.goods.length - 1];
        } else {
            goodsData = stableDataConfig.goods[useHealthItemTimes];
        }

        // 道具数量是否足够
        if (goodsData != null) {
            BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
            GoodsData[] result = bagInfo.rechargIfItemNotEnghou(goodsData);
            if (result == null) {
                playerController.sendWarn(WordFactory.GOODS_NOT_ENOUGH, goodsData.id);
                return;
            }
            bagInfo.subGoods(result); // 扣除道具
        }
        // 加血
        spritePlayerBean.getBattleTemp().addHp(0.3d);

        // 增加道具总使用次数
        playerController.getPlayer().getExtInfo(SettingInfo.class).getAutoRecover().addUseTimes(ConstantFactory.PROP_TYPE_RECOVER);

        // 推送血量更新
        SendUtils.sendWorldMapHPUpdate(playerController);

        SendUtils.sendWorldMapUserPropInfo(playerController, ConstantFactory.PROP_TYPE_RECOVER, useHealthItemTimes+1);
    }

    /**
     * 增加血量 不计算药品使用次数
     * @param playerController
     * @param spritePlayerBean
     */
    private void useRecoverNoTimes(PlayerController playerController, SpritePlayerBean spritePlayerBean){
        // 血量是否满
        if (spritePlayerBean == null || spritePlayerBean.getBattleTemp().isFullByLive()) {
            playerController.sendWarn(WordFactory.HP_IS_FULL);
            return;
        }

        if (!spritePlayerBean.isFree() && !spritePlayerBean.isMove() && !spritePlayerBean.isWait() && !spritePlayerBean.isMatch()) {
            LogUtils.error("只有空闲、行动、待命、匹配状态允许使用 -> " + spritePlayerBean.getStatus());
            playerController.sendWarn(WordFactory.STATUS_ERROR);
            return;
        }
        // 加血
        spritePlayerBean.getBattleTemp().addHp(0.3d);
        // 推送血量更新
        SendUtils.sendWorldMapHPUpdate(playerController);
    }

    /**
     * 复活 不计算药品使用次数
     * @param playerController
     * @param spritePlayerBean
     */
    private void useReviceNoTimes(PlayerController playerController, SpritePlayerBean spritePlayerBean){
        // 是否有卡牌未死亡
        if (spritePlayerBean == null || !spritePlayerBean.getBattleTemp().cardHasDie()) {
            playerController.sendWarn(WordFactory.CARD_NOT_DIE);
            return;
        }

        if (!spritePlayerBean.isFree() && !spritePlayerBean.isMove() && !spritePlayerBean.isWait() && !spritePlayerBean.isMatch()) {
            LogUtils.error("只有空闲、行动、待命、匹配状态允许使用 -> " + spritePlayerBean.getStatus());
            playerController.sendWarn(WordFactory.STATUS_ERROR);
            return;
        }

        // 加血
        spritePlayerBean.getBattleTemp().revive(0.3d);

        // 推送血量更新
        SendUtils.sendWorldMapHPUpdate(playerController);
    }

    private void useReviveItem(PlayerController playerController, SpritePlayerBean spritePlayerBean) {
        // 是否有卡牌未死亡
        if (spritePlayerBean == null || !spritePlayerBean.getBattleTemp().cardHasDie()) {
            playerController.sendWarn(WordFactory.CARD_NOT_DIE);
            return;
        }

        if (!spritePlayerBean.isFree() && !spritePlayerBean.isMove() && !spritePlayerBean.isWait() && !spritePlayerBean.isMatch()) {
            LogUtils.error("只有空闲、行动、待命、匹配状态允许使用 -> " + spritePlayerBean.getStatus());
            playerController.sendWarn(WordFactory.STATUS_ERROR);
            return;
        }

        // 判断道具是否足够
        StableDataConfig stableDataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY,
                E_StableDataType.REVIVE_NORMAL.getCode());
        if (stableDataConfig == null) {
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        int reviveTimes = playerController.getPlayer().getExtInfo(SettingInfo.class).getAutoRecover().getUseTimes(ConstantFactory.PROP_TYPE_REVIVE);
        GoodsData goodsData;
        if (reviveTimes >= stableDataConfig.goods.length) {
            goodsData = stableDataConfig.goods[stableDataConfig.goods.length - 1];
        } else {
            goodsData = stableDataConfig.goods[reviveTimes];
        }

        if (goodsData != null) {
            BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
            GoodsData[] result = bagInfo.rechargIfItemNotEnghou(goodsData);
            if (result == null) {
                playerController.sendWarn(WordFactory.GOODS_NOT_ENOUGH, goodsData.id);
                return;
            }
            bagInfo.subGoods(result); // 扣除道具
        }

        // 加血
        spritePlayerBean.getBattleTemp().revive(0.3d);

        // 增加复活次数
        playerController.getPlayer().getExtInfo(SettingInfo.class).getAutoRecover().addUseTimes(ConstantFactory.PROP_TYPE_REVIVE);

        // 推送血量更新
        SendUtils.sendWorldMapHPUpdate(playerController);

        SendUtils.sendWorldMapUserPropInfo(playerController, ConstantFactory.PROP_TYPE_REVIVE, reviveTimes+1);
    }

    /**
     * 膜拜
     *
     * @param playerController
     * @param data
     * @param code
     */
    private void worship(PlayerController playerController, byte[] data, int code) throws Exception {
        SGMapProto.C2S_MapWorship request = null;
        try {
            request = SGMapProto.C2S_MapWorship.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
        String playerIndex = request.getPlayerIndex();
        /**
         * 1.判断是否存在该玩家在前三 2.今日是否已经膜拜过了
         */
        // 获取上周排行前三的人
        WorldManager worldManager = GameServer.getInstance().getWorldManager();
        List<WorldRankBean> rankBeanList = worldManager.getRankList(SGCommonProto.E_RANK_TYPE.RANK_TYPE_MAPLASTWEEK);
        boolean flag = false;
        for (WorldRankBean worldRankBean : rankBeanList) {
            if (worldRankBean.getObjectIndex().equals(playerIndex)) {
                flag = true;
            }
        }
        if (!flag) {
            // 膜拜玩家不存在
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }
        if (!playerController.getPlayer().getWorldMapKillData().isAlreadyWorship(playerIndex)) {
            playerController.sendWarn(WordFactory.MAP_ALREADY_WORSHIP);
            return;
        }
        // 发放奖励 TO DO
        StableDataConfig stableDataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY,
                E_StableDataType.HEGEMONY_WORSHIP_VALUE.getCode());
        if (stableDataConfig != null) {
            BagInfo bagInfo = playerController.getPlayer().getBagInfo();
            bagInfo.addGoods(stableDataConfig.getGoodsData(0));
//            膜拜屏蔽掉私聊
//            // 如果是本服发私聊
//            SGCommonProto.E_MAP_HEGEMONY_RANK_TYPE status = worldManager
//                    .getRankStatus(SGCommonProto.E_RANK_TYPE.RANK_TYPE_MAPLASTWEEK);
//            if (status != null && status.equals(SGCommonProto.E_MAP_HEGEMONY_RANK_TYPE.WORLD_MAP_RANk_CURRENT_DRESS)) {
//                if (!playerController.getObjectIndex().equals(playerIndex)){
//                    LogUtils.debug("can worship sendPrivacy .... ");
//                    SGPlayerProto.C2S_MailSendPrivacyMail.Builder msp = SGPlayerProto.C2S_MailSendPrivacyMail.newBuilder();
//                    msp.setContent(WordFactory.getWord(WordFactory.MAP_WORSHIP_CONTENT));
//                    RankPlayerDetail rankPlayerDetail = worldManager.getRankPlayer(playerIndex);
//                    msp.setNickName(rankPlayerDetail.getName());
//                    msp.setPrivacyMailType(SGCommonProto.E_PRIVACY_MAIL_SENDER_TYPE.MAIL_PRIVACY_MAIL_TYPE_SINGLE);
//                    msp.setMailSendType(SGCommonProto.E_MAIL_SENDER_TYPE.MAIL_SENDER_TYPE_SENDER);
//                    msp.setTargetIndex(playerController.getObjectIndex());
//                    MailMsgChannel mailMsgChannel = (MailMsgChannel)SpringContext.getMessageChannel(MailMsgChannel.class);
//                    mailMsgChannel.sendPrivacy(playerController, msp.build(),playerController.getPlayer().getExtInfo(MailInfo.class), new Object());
//                }
//            }
        }
        playerController.getPlayer().getWorldMapKillData().addWorship(playerIndex);
        //
        SGMapProto.S2C_MapWorship.Builder response = SGMapProto.S2C_MapWorship.newBuilder();
        response.setPlayerIndex(playerIndex);
        playerController.sendMsg(code, response.build().toByteArray());
    }

    /**
     * 获取城市掉落
     *
     * @param playerController
     * @param data
     * @param code
     */
    private void getCityDrop(PlayerController playerController, byte[] data, int code, SpritePlayerBean spritePlayerBean) {
        SGMapProto.C2S_HegemonyGetCityDrop request = null;
        try {
            request = SGMapProto.C2S_HegemonyGetCityDrop.parseFrom(data);
        } catch (Exception e) {
            e.printStackTrace();
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }
        /**
         * 0.判断玩家是否在这个城市
         * 1.根据城市id 和 掉落的id 判断奖励是否存在
         * 2.存在的话获取配置
         * 3.根据配置读取持续时间与开始时间相加 +2秒 与当前时间做比较
         * 4.清空该城市上的掉落
         * 5.在结束时间内 发放奖励
         * 6.返回客户端的结果
         * 第1 2 3 4 5步在worldMapData中进行 并与生成奖励cityDrop做互斥
         */
        if (spritePlayerBean == null) {
            //玩家没有大地图信息
            LogUtils.error("player:" + playerController.getName() + " not in WorldMap");
            playerController.sendWarn(WordFactory.PLAYER_NOT_IN_WORLD_MAP);
            return;
        }
        if (spritePlayerBean.getCurCity() != request.getCityId()) {
            //玩家不再这个城
            playerController.sendWarn(WordFactory.PLAYER_NOT_IN_CITY);
            return;
        }

        WorldMapData worldMapData = WorldInfoFactory.getInstance().getWorldMapData(spritePlayerBean.getMasterPlayerIndex());
        CityDropConfig config;
        synchronized (worldMapData.getCityMap()) {
            CityBean cityBean = worldMapData.getCityMap().get(request.getCityId());
            //判断这个城市是否属于己方
            //判断这个城市是否处于和平状态
            if (cityBean.camp != playerController.getPlayer().camp){
                playerController.sendWarn(WordFactory.CITY_CAMP_DIFFERENT);
                LogUtils.error("can‘t get reward,because city camp different camp:->" + cityBean.camp);
                return;
            }

            if (cityBean.getStatus() != SGCommonProto.E_CITY_STATUS.CITY_STATUS_PEACE){
                LogUtils.error("can‘t get reward,because city not peace cityStatus:->" + cityBean.getStatus());
                playerController.sendWarn(WordFactory.CITY_NOT_PEACE);
                return;
            }
            TwoTuple<CityDropBean,Integer> twoTuple = worldMapData.getDropReward(cityBean,playerController);
            if(twoTuple.getFirst() == null){
                //城市掉落不存在
                playerController.sendWarn(WordFactory.CITY_DROP_NOT_HAVE);
                return;
            }
            SGMapProto.S2C_HegemonyGetCityDrop.Builder response = SGMapProto.S2C_HegemonyGetCityDrop.newBuilder();
            response.setCityId(request.getCityId());
            response.setIsSuccess(true);
            playerController.sendMsg(code, response.build().toByteArray());
            config = DataFactory.getInstance().getGameObject(DataFactory.CITY_DROP, twoTuple.getSecond());
            twoTuple.getFirst().init();
        }
        PropConfig propConfig = null;
        AssetConfig assetConfig = null;
        CardConfig cardConfig = null;
        String name = "";
        if (config != null) {
            //获取道具
            BagInfo bagInfo = playerController.getPlayer().getBagInfo();
            if (config.useType == 1) {
                bagInfo.addGoods(config.rewardId);
                for (GoodsData gd:config.rewardId){
                    if(gd.type == SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_PROPS_VALUE){
                        propConfig = DataFactory.getInstance().getGameObject(DataFactory.PROP_KEY, gd.id);
                        name = propConfig.name;
                    }else if(gd.type == SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_ASSETS_VALUE){
                        assetConfig = DataFactory.getInstance().getGameObject(DataFactory.ASSET_KEY, gd.id);
                        name = assetConfig.name;
                    }else if(gd.type == SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_CARDS_VALUE){
                        cardConfig = DataFactory.getInstance().getGameObject(DataFactory.CARD_KEY, gd.id);
                        name = cardConfig.name;
                    }else {

                    }
                    playerController.sendWarn(WordFactory.CITY_DROP_GET_REWARD,name,gd.value);
                }
            }
            if (config.useType == 2) {
                //根据类型 如果是药直接用
                //如果是13 14 15 16 12 8 单独处理
                List<PropConfig> propConfigList = new ArrayList<>();
                for (GoodsData gd : config.rewardId) {
                    if (gd.type == SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_PROPS_VALUE){
                        propConfig = DataFactory.getInstance().getGameObject(DataFactory.PROP_KEY, gd.id);
                        if (propConfig.type == ConstantFactory.PROP_TYPE_BAG || propConfig.type == ConstantFactory.PROP_TYPE_CAMP_BOX) {
                            int droupConfigId = propConfig.effectValue;
                            if (propConfig.type == ConstantFactory.PROP_TYPE_CAMP_BOX) {
                                droupConfigId = propConfig.campDropGroup[playerController.getPlayer().camp - 1];
                            }
                            DropGroupConfig dropGroupConfig = DataFactory.getInstance().getGameObject(DataFactory.DROP_GROUP_KEY,
                                    droupConfigId);
                            dropGroupConfig.reward(playerController, gd.value);
                        }else if (propConfig.type == ConstantFactory.PROP_TYPE_MORE_MILITARY){
                            propConfigList.add(propConfig);
                        }else if (propConfig.type == ConstantFactory.PROP_TYPE_RECOVER){
                            useRecoverNoTimes(playerController,spritePlayerBean);
                        }else if(propConfig.type == ConstantFactory.PROP_TYPE_REVIVE){
                            useReviceNoTimes(playerController,spritePlayerBean);
                        }else if (propConfig.type == ConstantFactory.PROP_TYPE_MILITARY_CAPITAL){
                            //使用军资类道具
                            playerController.getPlayer().getExtInfo(SettingInfo.class).getAutoRecover().setMilitaryPropId(propConfig.id);
                            playerController.sendWarn(WordFactory.USE_PROP_MILITARY,propConfig.effectValue);
                        }else{
                            //获得物品
                            bagInfo.addGoods(gd);
                        }
                        name = propConfig.name;
                    }else {
                        bagInfo.addGoods(gd);
                        if (gd.type == SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_ASSETS_VALUE){
                            assetConfig = DataFactory.getInstance().getGameObject(DataFactory.ASSET_KEY, gd.id);
                            name = assetConfig.name;
                        }else if(gd.type == SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_CARDS_VALUE){
                            cardConfig = DataFactory.getInstance().getGameObject(DataFactory.CARD_KEY, gd.id);
                            name = cardConfig.name;
                        }
                    }
                    playerController.sendWarn(WordFactory.CITY_DROP_USE_REWARD,name,gd.value);
                }
                if (propConfigList.size() > 0) {
                    HegemonyScoreChangeBean changeBean = playerController.getPlayer().getWorldMapKillData().useMilitary(propConfigList);
                    SendUtils.sendHegemoneyChange(playerController, changeBean);
                }
            }
        }
    }

}
